/*
 * MIT License
 *
 * Copyright (c) 2025 milkpotatoes
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

import { RunnerTest, TestLevel } from "./test-framework";

const testLvelArray = [TestLevel.L0, TestLevel.L1, TestLevel.L2, TestLevel.L3, TestLevel.L4];

export async function runSuit(suit: RunnerTest): Promise<void> {
    if (process.exitCode === undefined) {
        process.exitCode = 0;
    }
    if (process.argv.length == 3) {
        const arg = process.argv[2];
        let level = 0
        if (arg.startsWith('@') && Reflect.has(TestLevel, arg.substring(1))) {
            level |= Reflect.get(TestLevel, arg.substring(1));
        } else if (arg.startsWith('!') && Reflect.has(TestLevel, arg.substring(1))) {
            const expectedLevel = Reflect.get(TestLevel, arg.substring(1));
            for (const lv of testLvelArray) {
                if (lv != expectedLevel) {
                    level |= lv;
                }
            }
        } else if (Reflect.has(TestLevel, arg)) {
            const maxLevel = Reflect.get(TestLevel, arg);
            for (const lv of testLvelArray) {
                if (lv > maxLevel) {
                    break;
                }
                level |= lv;
            }
        } else {
            await suit.run(arg);
            return;
        }
        process.exitCode += await suit.run(level);
        return;
    }
    if (process.argv.length > 3) {
        const [, , ...args] = process.argv;
        process.exitCode += await suit.run(args);
        return;
    }
    process.exitCode += await suit.run();
}